package org.mv.mm.docs.nodes;

import java.beans.PropertyChangeEvent;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.mv.mm.api.Doc;
import org.mv.mm.api.Fragment;
import org.mv.mm.api.capabilities.IReloadableFragmentCapability;
import org.mv.mm.api.data.IDataProvider;
import org.openide.nodes.*;

/**
 *
 * @author Martin
 */
class FragmentNodeChildFactory extends ChildFactory<Fragment> implements NodeListener {

  private IDataProvider dataProvider;
  private Fragment fragment;
  private Doc doc;
  private boolean lRoot = false;
  private static final Logger logger = Logger.getLogger(FragmentNodeChildFactory.class.getName());

  /**
   * Called by typical node.
   *
   * @param dataProvider
   * @param fragment
   */
  public FragmentNodeChildFactory(IDataProvider dataProvider, Fragment fragment, Doc doc) {
    this.dataProvider = dataProvider;
    this.fragment = fragment;
    this.doc = doc;
  }

  /**
   * Called only by root node (root fragment).
   *
   * @param dataProvider IDataProvider
   */
  public FragmentNodeChildFactory(IDataProvider dataProvid, Doc doc) {
    this.dataProvider = dataProvid;
    this.doc = doc;

    // tells that the factory creates first level nodes (in root)
    this.lRoot = true;
  }

  @Override
  protected boolean createKeys(List<Fragment> list) {
    if (!Thread.interrupted()) { // should be called for some occasions of closed node etc.
      // get this ability from the lookup ...
      IReloadableFragmentCapability r = dataProvider.getLookup().lookup(IReloadableFragmentCapability.class);
      // ... and  use the ability
      if (r != null) {
        try {
          // Reloads fragments from disk/db
          r.reload();

          // Now populate the list of child entities...
          if (lRoot) {
            list.addAll(doc.getFirstLevelFragments());
          } else {
            list.addAll(fragment.getChildrenFragments());
          }

        } catch (Exception e) {
          logger.log(Level.WARNING, null, e); //TODO provide a message from Bundle
        }
      }
    }
    // And return true since we're all set
    return true;
  }

  @Override
  protected Node createNodeForKey(Fragment key) {
    FragmentNode chapterNode;

    List<Fragment> childrenFrags = key.getChildrenFragments();
    if (childrenFrags == null || childrenFrags.isEmpty()) {
      chapterNode = new FragmentNode(true, key, doc, dataProvider);
    } else {
      chapterNode = new FragmentNode(false, key, doc, dataProvider);
    }


    chapterNode.addNodeListener(this);
    return chapterNode;
  }

  @Override
  public void childrenAdded(NodeMemberEvent nme) {
    System.out.println("childrenAdded");
    //TODO or nothing
  }

  @Override
  public void childrenRemoved(NodeMemberEvent nme) {
    System.out.println("childrenRemoved");
    //TODO or nothing
  }

  @Override
  public void childrenReordered(NodeReorderEvent nre) {
    System.out.println("childrenReordered");
    //TODO or nothing
  }

  @Override
  public void nodeDestroyed(NodeEvent ne) {
    refresh(true);
  }

  @Override
  public void propertyChange(PropertyChangeEvent evt) {
    //TODO or nothing
  }
}
